﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Documents.Common.Interfaces;
using System.Xml;
using Documents.Repository.BusinessObjects;
using Documents.Common.Helpers;
using Documents.Repository.Helpers;

namespace Documents.Repository.Controllers
{
    public class DocumentController : Controller, IDocumentRepository
    {
        public ActionResult Index()
        {
            return null;
        }

        public ActionResult CareEvents()
        {
            DocumentClassesDataContext db = new DocumentClassesDataContext();
            var careevents = db.CareEvents;
            XmlDocument result = new XmlDocument();
            XmlNode container = result.CreateNode(XmlNodeType.Element, "", "CareEvents", "");

            foreach (CareEvent ce in careevents)
            {
                ce.DocumentSets.Clear();
                container.AppendChild(SerializeResponse(result, ce, "CareEvent"));
            }
            result.AppendChild(container);

            return new ContentResult
            {
                Content = result.OuterXml,
                ContentType = "application/xml"
            };
        }

        public ActionResult CareEvent(string careEventID)
        {
            Guid ceid = new Guid(careEventID);
            DocumentClassesDataContext db = new DocumentClassesDataContext();
            var docs = db.vwHeadDocuments.Where(o => o.CareEventID == ceid);
            return DocumentList(docs);
        }

       

        /// <summary>
        /// Returns a set of categories, either from root or from a parent
        /// </summary>
        /// <param name="parentCategory"></param>
        /// <returns></returns>
        public ActionResult Categories(Guid? parentCategory)
        {
            DocumentClassesDataContext db = new DocumentClassesDataContext();
            var categories = db.Categories;
            XmlDocument result = new XmlDocument();
            XmlNode container = result.CreateNode(XmlNodeType.Element, "", "categories", "");
            SerializeCategories(categories, result, container);
            result.AppendChild(container);
            return new ContentResult
            {
                Content = result.OuterXml,
                ContentType = "application/xml"
            };
        }

        private void SerializeCategories(System.Data.Linq.Table<Category> categories, XmlDocument result, XmlNode container)
        {
            foreach (Category c in categories)
            {
                List<Documents.Common.Models.Lite.DocumentType> doctypes = new List<Documents.Common.Models.Lite.DocumentType>();
                foreach (DocumentType_Category dtc in c.DocumentType_Categories)
                    doctypes.Add(ObjectHelper.Get(dtc.DocumentType));
                c.DocumentType_Categories.Clear();
                XmlNode category = SerializeResponse(result, c, "Category");

                foreach (Documents.Common.Models.Lite.DocumentType dt in doctypes)
                    category.AppendChild(SerializeResponse(result, dt, "DocumentType"));

                container.AppendChild(category);
            };
        }

        
        /// <summary>
        /// Returns an individual category
        /// </summary>
        /// <param name="categoryID"></param>
        /// <returns></returns>
        public ActionResult Category(Guid categoryID)
        {
            return null;
        }

        public ActionResult Document(Guid documentID)
        {
            DocumentClassesDataContext db = new DocumentClassesDataContext();
            vwDocument doc = db.vwDocuments.Where(o => o.DocumentID == documentID).FirstOrDefault();
            XmlDocument result = new XmlDocument();
            SerializeResponse(result,result,doc,"document");
            return new ContentResult
            {
                Content = result.OuterXml,
                ContentType = "application/xml"
            };
        }


        /// <summary>
        /// returns the 'Head' document details for each document.
        /// </summary>
        /// <param name="categoryID"></param>
        /// <returns></returns>
        public ActionResult Documents(string documentType)
        {
            return null;
        }


     

        private ActionResult DocumentList(IEnumerable<vwHeadDocument> docs)
        {
            XmlDocument result = new XmlDocument();
            XmlNode container = result.CreateNode(XmlNodeType.Element, "", "documents", "");
            result.AppendChild(container);
            foreach (vwHeadDocument d in docs)
                SerializeResponse(result, container, ObjectHelper.Get(d), "document");

            return new ContentResult
            {
                Content = result.OuterXml,
                ContentType = "application/xml"
            };
        }

        public ActionResult History(Guid DocumentSetID)
        {
            XmlDocument result = new XmlDocument();
            XmlNode history = result.CreateNode(XmlNodeType.Element, "", "history", "");
            result.AppendChild(history);
            var selectedCategory = Request["selectedCategory"];

            DocumentClassesDataContext db = new DocumentClassesDataContext();
            var documents = db.vwDocumentHistories.Where(o => o.DocumentSetID == DocumentSetID).OrderBy(o=>o.DocumentPosition);

            foreach (vwDocumentHistory v in documents)
                SerializeResponse(result,history, v, "version");
            return new ContentResult
            {
                Content = result.OuterXml,
                ContentType = "application/xml"
            };
        }
        private XmlNode SerializeResponse(XmlDocument result, object v, string elementname)
        { 
            XmlNode node = XmlHelper.Serialize(v);
            XmlNode docnode = result.CreateNode(XmlNodeType.Element, "", elementname, "");
            docnode.InnerXml = node.InnerXml;
            return docnode;
        }


        private void SerializeResponse(XmlDocument result, XmlNode parent, object v, string elementname)
        {
            XmlNode node = SerializeResponse(result,v,elementname);
            parent.AppendChild(node);
        }

        public ActionResult Search(object searchCriteria)
        {
            return null;
        }


        public ActionResult Revoke(Guid documentID)
        {
            DocumentClassesDataContext db = new DocumentClassesDataContext();
            Document d = db.Documents.Where(o => o.DocumentID == documentID).FirstOrDefault();
            d.Revoked = true;
            db.SubmitChanges();
            return RedirectToAction("Document", new {documentID = documentID});
        }

        public ActionResult Create(string DocumentType)
        {
            return null;
        }


        public ActionResult Countersign(Guid documentID)
        {
            return null;
        }

        public ActionResult Edit(Guid documentID)
        {
            return null;
        }

        public ActionResult Duplicate(Guid documentID)
        {
            return null;
        }

        [HttpPost]
        public ActionResult Store(XmlDocument document)
        {
            Document d = new Document();
            d.DocumentAuthor = Request["documentauthor"];
            d.DocumentCreationDate = DateTime.Now;
            d.DocumentTypeCode = Request["documenttypecode"];
            d.DocumentID = Guid.NewGuid();
            d.Revoked = false;
            d.DocumentTitle = "Hey! I created this";
            DocumentClassesDataContext db = new DocumentClassesDataContext();
            DocumentSet set = new DocumentSet();
            set.DocumentSetID = Guid.NewGuid();
            set.DocumentPosition = 0;
            set.Document = d;
            DocumentType dt = (from documenttype in db.DocumentTypes where documenttype.DocumentTypeCode == d.DocumentTypeCode select documenttype).Single();
            d.DocumentType = dt;
            db.Documents.InsertOnSubmit(d);
            db.SubmitChanges();

            XmlDocument result = new XmlDocument();
            XmlNode storeresult = result.CreateNode(XmlNodeType.Element, "storeresult", "");

            AddSimpleNode("documentsetid", storeresult, result, set.DocumentSetID.ToString());
            AddSimpleNode("documentid", storeresult, result, d.DocumentID.ToString());

            result.AppendChild(storeresult);
            return new ContentResult
            {
                Content = result.OuterXml,
                ContentType = "application/xml"
            };
        }

        private void AddSimpleNode(string nodename, XmlNode storeresult, XmlDocument result, string value)
        {
            XmlNode documentsetid = result.CreateNode(XmlNodeType.Element, nodename, "");
            documentsetid.InnerText = value;
            storeresult.AppendChild(documentsetid);
        }

    }
}
